﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Enterprise.Framework.DomainModel;
using Resto.CostControl.Core.Enums;
using Enterprise.Framework.DomainModel.Repositories;
using Enterprise.Framework.Core.Exceptions;
using Resto.CostControl.Core.Domain.Resource;
using Enterprise.Framework.DomainModel.Specifications;
using Resto.CostControl.Common.Utility;

namespace Resto.CostControl.Core.Domain.Model
{
    /// <summary>
    /// 菜肴发货单
    /// </summary>
    public partial class DishDelivery : IAggregationRoot
    {
        #region 构造函数

        internal DishDelivery()
        {
            this.State = DishDeliveryState.None.ToString();
            this.ID = IDHelper.CreateNewID();
        }

        #endregion

        #region 私有属性

        private IEntityRepository<DishDelivery> _Repository;
        private IEntityRepository<DishDelivery> Repository
        {
            get
            {
                if (_Repository == null)
                    _Repository = RestoCostDomainSession.CurrentSession.CreateEntityRepository<DishDelivery>();

                return _Repository;
            }
        }

        #endregion

        #region 业务方法

        internal void Add()
        {
            Validate();

            this.CreateAudit = new Audit();
            this.LastUpdateAudit = new Audit();

            this.Repository.Add(this);
        }

        internal void Update()
        {
            Validate();

            this.LastUpdateAudit = new Audit();

            this.Repository.Update(this);
        }

        internal void Delete()
        {
            this.Repository.Delete(this);
        }

        internal void AddItem(DishDeliveryItem item)
        {
            bool result = this.Items.Where(p => p.MaterialID == item.MaterialID).Count() > 0;
            if (result)
                throw new BusinessValidationException(DishDeliveryResource.ValidateException_DeliveryItem_Repeat);

            this.Items.Add(item);
        }

        internal void RemoveItem(string itemID)
        {
            DishDeliveryItem item = this.Items.Where(p => p.ID == itemID).FirstOrDefault();
            if (item != null)
            {
                this.Items.Remove(item);
                item.Delete();
            }
        }

        internal DishDeliveryItem GetItem(string itemID)
        {
            return this.Items.Where(p => p.ID == itemID).FirstOrDefault();
        }

        //internal void ClearItems()
        //{
        //    DishDeliveryItem[] array = this.Items.ToArray();
        //    foreach (DishDeliveryItem item in array)
        //        item.Delete();

        //    this.Items.Clear();
        //}

        internal void UpdateState(DishDeliveryState state)
        {
            DishDeliveryState currentState = (DishDeliveryState)Enum.Parse(typeof(DishDeliveryState), this.State);

            if (currentState == DishDeliveryState.Sign)
                throw new BusinessException(DishDeliveryResource.ValidateException_DeliveryState_UpdateEnd);

            if (currentState.GetHashCode() <= state.GetHashCode())
            {
                this.State = state.ToString();
            }
            else
            {
                string message = string.Format(DishDeliveryResource.ValidateException_DeliveryState_NotUpdate, this.State, state.ToString());
                throw new BusinessException(message);
            }
        }

        #endregion

        #region 验证方法

        protected void Validate()
        {
            List<string> messageList = new List<string>();

            ValidateCodeRepeat(messageList);

            if (messageList.Count > 0)
                throw new BusinessValidationException(messageList.ToArray());
        }


        private void ValidateCodeRepeat(IList<string> messageList)
        {
            ISpecification<DishDelivery> spec = Specification<DishDelivery>.Create(p => p.Code == this.Code);
            spec = spec.And(Specification<DishDelivery>.Create(p => p.ID != ID));

            bool result = Repository.Count(spec) > 0;
            if (result)
                messageList.Add(string.Format(DishDeliveryResource.ValidateException_DeliveryCode_Repeat, this.Code));
        }

        #endregion
    }
}
